package com.huitone.smspfm.core.filter;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

import com.huitone.smspfm.logger.ExtLogger;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import com.bin.common.utils.DateTimeUtils;
import com.bin.common.utils.MD5Util;
import com.bin.common.utils.StringUtils;
import com.huitone.smspfm.core.config.AppStaticConfigs;
import com.huitone.smspfm.core.constant.DealResult;
import com.huitone.smspfm.core.filter.wdog.ReapMsgFilterTaskWatchDog;
import com.huitone.smspfm.model.SmsEntityForMt;
import com.huitone.smspfm.redis.model.AppCanstant;

/**   
* @Title RepeatMsgFilterTask.java 
* @Package com.huitone.smspfm.core.task 
* @Description TODO(用一句话描述该文件做什么) 
* @author ybliang   
* @date 2017年6月18日 上午10:40:15 
* @version V1.0   
*/
public class RepeatMsgFilterTask extends Thread {
	
	private ExtLogger logger = ExtLogger.create(RepeatMsgFilterTask.class);
	
	public static ReapMsgFilterTaskWatchDog watchDog = null; // 重复集合中过期的值
	
	private String moduleName = "重复短信过滤模块";
	
	private byte[] moduleNameB = AppStaticConfigs.stringRedisSerializer.serialize(moduleName); 
	
	private List<SmsEntityForMt> entities = null;
	
	private CyclicBarrier barrier = null;
	
	public RepeatMsgFilterTask(List<SmsEntityForMt> entities, CyclicBarrier barrier) {
		this.entities = entities;
		this.barrier = barrier;
		/*if (watchDog == null || !watchDog.isAlive()) {
			watchDog = new ReapMsgFilterTaskWatchDog();
			watchDog.start();
		}*/
	}

	@Override
	public void run() {
		
		if (entities == null) return;
		
		long start = System.currentTimeMillis();
		
		List<List<List<String>>> tmp = new ArrayList<>();
		
		List<String> args = new ArrayList<>();
		
		int size = entities.size();
		for (int i = 0 ; i < size ; i ++) {
			
			StringBuffer buffer = new StringBuffer();
			
			SmsEntityForMt smsEntity = entities.get(i);
			
			String srvNode = StringUtils.toString(smsEntity.getSrvNode());
			String serviceCode = StringUtils.toString(smsEntity.getServiceCode());
			
			List<String> list = new ArrayList<>(); // 所有适用的规则
			
			Set<String> set1 = AppStaticConfigs.configRepeatMap.get(srvNode + ":" + serviceCode);
			if (set1 != null) {
				list.addAll(set1);
			}
			Set<String> set2 = AppStaticConfigs.configRepeatMap.get(srvNode + ":");
			if (set2 != null) {
				list.addAll(set2);
			}
			Set<String> set3 = AppStaticConfigs.configRepeatMap.get(":" + serviceCode);
			if (set3 != null) {
				list.addAll(set3);
			}
			Set<String> set4 = AppStaticConfigs.configRepeatMap.get(":");
			if (set4 != null) {
				list.addAll(set4);
			}
			
			List<List<String>> ruleHashs = getRuleHashs(list, smsEntity);
			int rhsize = ruleHashs.size();
			for (int j = 0 ; j < rhsize; j ++) {
				String encode = ruleHashs.get(j).get(0);
				buffer.append(encode);
				if (j < rhsize - 1) {
					buffer.append(":");
				}
			}
			
			args.add(buffer.toString());
			
			tmp.add(ruleHashs);
		}
		
		List<Long> indexes = AppStaticConfigs.scriptOpts2
				.getListLong(new DefaultRedisScript<>(AppStaticConfigs.luaRepeatChecker, List.class),
						Collections.singletonList(AppStaticConfigs.iSMRepZSet), args.toArray());
		
		List<List<List<String>>> rules = tmp;
		
		for (int i = 0 ; i < entities.size() ; i ++) {
			
			SmsEntityForMt entity = entities.get(i);
			
			Map<byte[], byte[]> hashMap = new HashMap<>();
			hashMap.put(AppCanstant.SmsEntity.DealModuleName, moduleNameB);
			hashMap.put(AppCanstant.SmsEntity.SdealTime, AppStaticConfigs.stringRedisSerializer.serialize(DateTimeUtils.dateToStr2(new Date())));
			
			if (indexes.get(i) == 1) {
				
				entity.setDealResultCodeMap(moduleName, DealResult.RESULT_2);
				entity.setInterceptedCode(DealResult.RESULT_2);
				entity.setInterceptedDesc(DealResult.RESULT_2_DESC);
				entity.setIntercepted(true);
				
				logger.debug("[序列号:用户号码][" + entity.getSerialno() + ":" + entity.getPhoneNumber() + "]被重复数据过滤器捕获,处理流程结束。");
				
			} else { // 只有正常通过时才写重复hash
				
				entity.setDealResultCodeMap(moduleName, DealResult.RESULT0);
				
				entity.setRepeatEncodes(rules.get(i));
				
			}
		}
		
		long end = System.currentTimeMillis();
		
		logger.debug("重复过滤执行完毕,共耗时:" + (end - start) + "毫秒");
		
		try {
			barrier.await();
		} catch (InterruptedException | BrokenBarrierException e) {
			e.printStackTrace();
		}
	}
	
	public List<List<String>> getRuleHashs(List<String> repeatRules, SmsEntityForMt entity) {
		
		List<List<String>> result = new ArrayList<>();
		
		if (repeatRules != null && entity != null) {
			for (String repeatRule:repeatRules) {
				if (StringUtils.isEmpty(repeatRule)) continue;
				String[] strings = repeatRule.split(":");
				String srvNode = strings[0];
				//String serviceCode = strings[1];
				String smSeqFlag = strings[2];
				String userFlag = strings[3];
				String serviceCodeFlag = strings[4];
				String smFlag = strings[5];
				String timeLen = strings[6];
				String ruleId = strings[7];
				
				StringBuffer buffer = new StringBuffer();
				
				if (!StringUtils.isEmpty(srvNode)) { // 对特定业务端进行去重
					buffer.append(StringUtils.toString(entity.getSrvNode()));
				}
				
				if ("1".equals(serviceCodeFlag)) { // 对特定短信业务进行去重
					buffer.append(StringUtils.toString(entity.getServiceCode()));
				}
				
				if ("1".equals(smSeqFlag)) {
					buffer.append(StringUtils.toString(entity.getSerialno()));
				}
				
				if ("1".equals(userFlag)) {
					buffer.append(StringUtils.toString(entity.getPhoneNumber()));
				}
				
				if ("1".equals(smFlag)) {
					buffer.append(StringUtils.toString(entity.getContent()));
				}
				
				if (StringUtils.isEmpty(buffer.toString())) continue;
				
				String encode = MD5Util.encode(buffer.toString());
				
				List<String> tmpList = new ArrayList<>();
				tmpList.add(encode);
				tmpList.add(timeLen);
				tmpList.add(ruleId);
				
				result.add(tmpList);
			}
		}
		
		return result;
	}

}
